﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace HWR_Ants.Classes.Obsolete_2
{
    [Obsolete]
    class Ant
    {
        int startPoint;
        int currentPosition;
        SortedList<int, bool> hasVisited;
        IList<Point> listOfCities;
        bool finished;
        int cityFrom;
        int cityTo;
        double distanceWalked;
        double currentDistanceWalked;
        List<int> listOfWalkedCities;

        public Ant(int StartPoint, IList<Point> ListOfCities)
        {
            listOfWalkedCities = new List<int>();
            listOfWalkedCities.Add(StartPoint);
            startPoint = StartPoint;
            currentPosition = StartPoint;
            listOfCities = ListOfCities;

            hasVisited = new SortedList<int, bool>();

            for (int i = 0; i < listOfCities.Count; i++)
            {
                if (i != startPoint)
                    hasVisited.Add(i, false);
                else
                    hasVisited.Add(i, true);
            }
            finished = false;
            cityFrom = -1;
            cityTo = -1;
            distanceWalked = 0;
            currentDistanceWalked = 0;
        }

        public int CityTo
        {
            get { return cityTo; }
        }

        public int CityFrom
        {
            get { return cityFrom; }
        }

        public double CurrentDistanceWalked
        {
            get { return currentDistanceWalked; }
            set { currentDistanceWalked = value; }
        }

        public double DistanceWalked
        {
            get { return distanceWalked; }
            set { distanceWalked = value; }
        }

        public List<int> ListOfWalkedCities
        {
            get { return listOfWalkedCities; }
            set { listOfWalkedCities = value; }
        }

        private double[] getWahrscheinlichkeitNaechsteStadt()
        {
            IList<bool> hasVis = hasVisited.Values;
            double[] ret = new double[hasVis.Count];
            
            for (int i = 0; i < hasVis.Count; i++)
            {
                if (hasVis.ElementAt(i))
                {
                    ret[i] = 0;
                }
                else
                {
                    ret[i] = getProbability(i);
                }
            }

            return ret;
        }

        public bool WalkToNextCity()
        {
            int nextCity = -1;
            double currentProbability = 0;
            double[] probabilityOfNextCity = getWahrscheinlichkeitNaechsteStadt();

            for (int i = 0; i < probabilityOfNextCity.Length; i++)
            {
                if (!hasVisited[i])
                {
                    if ((probabilityOfNextCity[i] > currentProbability) || ((probabilityOfNextCity[i] != 0) && (currentProbability == 0)))
                    {
                        nextCity = i;
                        currentProbability = probabilityOfNextCity[i];
                    }
                }
            }

            if (nextCity == -1)
            {
                cityFrom = currentPosition;
                cityTo = startPoint;
                nextCity = startPoint;
                finished = true;
            }

            if (!finished)
            {
                cityFrom = currentPosition;
                cityTo = nextCity;
            }

            distanceWalked += Tools.Tools.ActiveDistanceTable.DistanceMatrix[CityFrom, cityTo];
            currentDistanceWalked = Tools.Tools.ActiveDistanceTable.DistanceMatrix[CityFrom, cityTo];
            currentPosition = nextCity;
            hasVisited[nextCity] = true;
            listOfWalkedCities.Add(nextCity);
            return finished;
        }

        //TODO: Wahrscheinlichkeit einer Route überprüfen
        private double getProbability(int city)
        {
            double zaehler = Tools.Tools.ProbabilityTable[currentPosition,city];
            double summe = 0;

            for (int i = 0; i < hasVisited.Count; i++)
            {
                if (!hasVisited.ElementAt(i).Value)
                {
                    summe += Tools.Tools.ProbabilityTable[currentPosition, i];
                }
            }
            if (summe == 0)
                return 0;

            summe -= zaehler;

            return (zaehler / summe);
        }

        [Obsolete]
        private double calculateProbability(int city)
        {
            double[,] dtMatrix = Tools.Tools.ActiveDistanceTable.DistanceMatrix;
            double[,] ptMatrix = Tools.Tools.ActivePheromonTable.PheromonMatrix;

            double tau = ptMatrix[currentPosition, city];
            double distance = dtMatrix[currentPosition, city];

            int alpha = Tools.Tools.ActiveCurrentOptions.Parameter.Alpha;
            int beta = Tools.Tools.ActiveCurrentOptions.Parameter.Beta;

            double zaehler = calculateTauDistance(alpha, beta, tau, distance);
            double summe = 0;

            for (int i = 0; i < hasVisited.Count; i++)
            {
                if (!hasVisited.ElementAt(i).Value)
                {
                    summe += calculateTauDistance(alpha, beta, tau, distance);
                }
            }
            // TODO: Calculate global setzen
            if (summe == 0)
                return 0;

            return (zaehler / summe);
        }

        [Obsolete]
        private double calculateTauDistance(int alpha, int beta, double tau, double distance)
        {
            return Math.Pow(tau, alpha) * Math.Pow(distance, beta);
        }

    }
}
